package com.ymx.darling.generater;

import com.ymx.darling.generater.config.GlobalConfig;
import com.ymx.darling.generater.config.StrategyConfig;
import com.ymx.darling.generater.table.Column;
import com.ymx.darling.generater.table.Table;
import com.ymx.darling.util.ObjectUtil;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 实体类生成器
 * @author 爱Java的小于
 */
public class EntityGenerator extends BaseGenerator {
    public EntityGenerator(GlobalConfig globalConfig, StrategyConfig strategyConfig) {
        super(globalConfig, strategyConfig);
    }

    public void createEntity(List<Table> tableList) {
        tableList.forEach(table -> {
            String className = this.toUpperCaseFirstOne(this.convertToCamelCase(table.getName()));
            String entityContent = TemplateContent.getContent("entity")
                .replace("{basePackage}", globalConfig.getBasePackage())
                .replace("{author}", globalConfig.getAuthor())
                .replaceAll("\\{imports}", this.splitImport(table))
                .replaceAll("\\{entity}", className)
                    .replace("{table}", table.getName())
                .replace("{fields}", this.splitProperty(table));
                if (strategyConfig.isLombok()) {
                     entityContent = entityContent.replace("{lombok}", "@Data")
                            .replace("{methods}", "");
                } else {
                    entityContent = entityContent.replace("{methods}", this.splitSetterAndGetter(table))
                            .replace("{lombok}", "");
                }
            // 将创建好的类写入到文件中
            String filePath = String.format("%s\\%s\\%s.java", this.getProjectAbsolutePath(), strategyConfig.getEntityPackageName(), className);
            this.createClass(filePath, entityContent);
        });
    }


    /**
     * 拼接字段属性
     * @param table table
     * @return String
     */
    private String splitProperty(Table table) {
        List<Column> columnList = table.getColumnList();
        StringBuilder propertyBuilder = new StringBuilder();
        columnList.forEach(column -> {
            String columnName = this.convertToCamelCase(column.getName());
            String typeName = ObjectUtil.getSimpleName(column.getJdbcType());
            if (columnName.equals("id")) {
                propertyBuilder.append("\t@Id\n");
            }
            String columnExpression = String.format("\tprivate %s %s;\n", typeName, columnName);
            propertyBuilder.append(columnExpression);
        });
        return propertyBuilder.toString();
    }


    /**
     * 拼接字段的set/get方法
     * @param table table
     * @return String
     */
    public String splitSetterAndGetter(Table table) {
        List<Column> columnList = table.getColumnList();
        StringBuilder setterGetterBuilder = new StringBuilder();
        columnList.forEach(column -> {
            String columnName = this.convertToCamelCase(column.getName());
            String typeName = ObjectUtil.getSimpleName(column.getJdbcType());
            String setMethod = String.format(
                "\tpublic void set%s(%s %s){\n" +
                    "\t\tthis.%s = %s;\n" +
                "\t}\n\n", this.toUpperCaseFirstOne(columnName), typeName, columnName, columnName, columnName);
            String getMethod = String.format(
                "\tpublic %s get%s(){\n" +
                    "\t\treturn this.%s;\n" +
                    "\t}\n\n", typeName, this.toUpperCaseFirstOne(columnName), columnName);
            setterGetterBuilder.append(setMethod);
            setterGetterBuilder.append(getMethod);
        });
        return setterGetterBuilder.toString();
    }


    /**
     * 拼接import内容
     * @param table table
     * @return String
     */
    private String splitImport(Table table) {
        StringBuilder importBuilder = new StringBuilder();
        Set<String> importSet = new HashSet<>(); // 确保import的唯一

        // 引入id的依赖
        if (table.isIdIsExist()) {
            importBuilder.append("import com.ymx.darling.bean.annotation.Id;\n");
        }
        table.getColumnList().forEach(column -> {
            String typeName = column.getJdbcType().getName();
            String[] typeNameSplit = typeName.split("\\.");
            if (typeNameSplit.length > 1 && !typeNameSplit[1].equals("lang")) {
                if (!importSet.contains(typeName)) {
                    importSet.add(typeName);
                    importBuilder.append(String.format("import %s;\n", typeName));
                }
            }
        });
        if (strategyConfig.isLombok()) {
            importBuilder.append("import lombok.Data;\n");
        }
        return importBuilder.toString();
    }
}
